﻿using Furion.Logging;
using IMES.Entity;
using SqlSugar;
using SqlSugar.IOC;
using System.Linq.Dynamic.Core;
using System.Linq.Expressions;
using System.Reflection;

namespace IMES.Setup
{
    /// <summary>
    /// 数据库配置
    /// </summary>
    public class SqlSugarSet
    {
        public static void AddSqlsugarSetup()
        {
            string sqlserverConn = System.Configuration.ConfigurationManager.AppSettings["SqlConn"].ToString();
            string isCodefirst = System.Configuration.ConfigurationManager.AppSettings["IsCodeFirst"].ToString();
            //string orcaleConn = System.Configuration.ConfigurationManager.AppSettings["OrcaleConn"].ToString();
            List<IocConfig> iocConfigs = new List<IocConfig>()
            {
                new IocConfig (){ ConnectionString=sqlserverConn,ConfigId=0,IsAutoCloseConnection=true,DbType=IocDbType.MySql},
                //new IocConfig (){ ConnectionString=orcaleConn,ConfigId=1,IsAutoCloseConnection=true,DbType=IocDbType.Oracle}
            };
            SugarIocServices.AddSqlSugar(iocConfigs);
            SugarIocServices.ConfigurationSugar(db =>
            {
                foreach (var iocItem in iocConfigs)
                {
                    SqlSugarProvider dbClient = db.GetConnection(iocItem.ConfigId);
                    SetQueryFilter(dbClient);
                    //sql执行语句日志
                    dbClient.Aop.OnLogExecuting = (sql, pars) =>
                    {
                        try
                        {
                            Log.Information(SqlProfiler.ParameterFormat(sql, pars));
                        }
                        catch (Exception ex)
                        {
                            Log.Error($"日志错误{ex.StackTrace}");
                        }
                    };
                }
            });
            if (isCodefirst == "1")
            {
                CreateTable(iocConfigs);
            }
        }
        /// <summary>
        /// 创建数据库表 codefirst
        /// </summary>
        private static void CreateTable(List<IocConfig> iocConfigs)
        {
            foreach (var item in iocConfigs)
            {
                string configId = Convert.ToString(item.ConfigId);
                ISqlSugarClient db = DbScoped.SugarScope.GetConnectionScope(configId);
                db.DbMaintenance.CreateDatabase();//没有数据库的时候创建数据库
                var tableLists = db.DbMaintenance.GetTableInfoList();
                var files = System.IO.Directory.GetFiles(AppDomain.CurrentDomain.BaseDirectory, "MyFurion.WFSqlsugar.Model.dll");
                if (files.Length > 0)
                {
                    Type[] types = Assembly.LoadFrom(files[0]).GetTypes().Where(it => it.BaseType == typeof(BaseEntity)).ToArray();
                    //Type[] types = Assembly.LoadFrom(files[0]).GetTypes().ToArray();
                    foreach (var entityType in types)
                    {
                        //创建数据表
                        string tableName = entityType.GetCustomAttribute<SugarTable>().TableName.ToLower();//根据特性获取表名称
                        var configid = entityType.GetCustomAttribute<TenantAttribute>()?.configId;//根据特性获取租户id
                        configid = configid == null ? "0" : configid.ToString();
                        if (!tableLists.Any(p => p.Name == tableName) && configId == configid.ToString())
                        {
                            //创建数据表包括字段更新
                            db.CodeFirst.InitTables(entityType);
                        }
                    }
                    db.Close();
                }
            }
        }
        /// <summary>
        /// 添加全局过滤器
        /// </summary>
        /// <param name="provider"></param>
        private static void SetQueryFilter(SqlSugarProvider provider)
        {
            //添加全局过滤器
            var files = System.IO.Directory.GetFiles(AppDomain.CurrentDomain.BaseDirectory, "MyFurion.WFSqlsugar.Model.dll");
            if (files.Length > 0)
            {
                Type[] types = Assembly.LoadFrom(files[0]).GetTypes().Where(it => it.BaseType == typeof(BaseEntity)).ToArray();
                foreach (var entityType in types)
                {
                    //string tableName = entityType.GetCustomAttribute<SugarTable>().TableName;//根据特性获取表名称
                    var lambda = DynamicExpressionParser.ParseLambda(new[] { Expression.Parameter(entityType, "it") },
                        typeof(bool), $"{nameof(BaseEntity.IsDeleted)} ==  @0", false);
                    provider.QueryFilter.Add(new TableFilterItem<object>(entityType, lambda, true)); //将Lambda传入过滤器
                }
            }
            //插入/更新过滤器,用于审计日志
            provider.Aop.DataExecuting = (oldValue, entityInfo) =>
            {
                //新增时操作
                if (entityInfo.OperationType == DataFilterType.InsertByObject)
                {

                }
                //修改时操作        
                if (entityInfo.OperationType == DataFilterType.UpdateByObject)
                {
                    if (entityInfo.PropertyName == "ModifyTime")
                    {
                        entityInfo.SetValue(DateTimeOffset.Now);//修改UpdateTime字段
                    }
                }
            };
        }
    }
}
